#include <iostream>
#include <string>
#include <gtest/gtest.h>
#include <memory>
#include "../mqcomm/Message.pb.h"
#include "../mqserver/virtualhost.hpp"
using namespace std;


class HostTest : public testing::Test {
public :
    static void SetUpTestCase()  {
        cout << "所有单元测试前执行，初始化总环境!" << endl; 
    }

    void SetUp() override {
        string basedir = "./data/host1/message/";
        _host = make_shared<rbmq::VirtualHost>("host1", basedir, "./data/host1/meta.db");
        unordered_map<string, string> empty_map;
        // 声明交换机
        _host->declareExchange("exchange1", mqNs::ExchangeType::DIRECT, true, false, empty_map);
        _host->declareExchange("exchange2", mqNs::ExchangeType::DIRECT, true, false, empty_map);
        _host->declareExchange("exchange3", mqNs::ExchangeType::DIRECT, true, false, empty_map);
        // 声明队列
        _host->declareQueue("queue1", true, false, false, empty_map);
        _host->declareQueue("queue2", true, false, false, empty_map);
        _host->declareQueue("queue3", true, false, false, empty_map);
        _host->declareQueue("queue4", true, false, false, empty_map);


        // 绑定
        _host->Bind("queue1", "exchange1", "music.game#sport");
        _host->Bind("queue1", "exchange2", "music.game#sport");
        _host->Bind("queue1", "exchange3", "music.game#sport");
        _host->Bind("queue2", "exchange3", "music.game#sport");
        _host->Bind("queue3", "exchange1", "music.game#sport");

        // 消息的发布
        mqNs::BasicProperties bp;
        bp.set_id(UuidHelper::uuid());
        bp.set_routing_key("hello");
        bp.set_delivery_mode(mqNs::DeliveryMode::DURABLE);
        _host->basicPublish("queue1", &bp, "hello world!1");
        _host->basicPublish("queue1", nullptr, "hello world!2");
        _host->basicPublish("queue1", nullptr, "hello world!3");

        _host->basicPublish("queue2", nullptr, "hello world!4");
        _host->basicPublish("queue3", nullptr, "hello world!5");
        _host->basicPublish("queue2", nullptr, "hello world!6");
        _host->basicPublish("queue3", nullptr, "hello world!7");


    }

    void TearDown() override {
        // _host->clear();

    }
    static void TearDownTestCase() {
        // 在这里清理公共的测试数据
        cout << "所有单元测试执行完毕后执行, 清理总环境!" << endl;
    }

    rbmq::VirtualHost::ptr _host;
};

TEST_F(HostTest, init_test) {
    ASSERT_EQ(_host->existsExchange("exchange1"), true);
    ASSERT_EQ(_host->existsExchange("exchange2"), true);
    ASSERT_EQ(_host->existsExchange("exchange3"), true);

    ASSERT_EQ(_host->existsQueue("queue1"), true);
    ASSERT_EQ(_host->existsQueue("queue2"), true);
    ASSERT_EQ(_host->existsQueue("queue3"), true);

    ASSERT_EQ(_host->existsBinding("exchange1", "queue1"), true);
    ASSERT_EQ(_host->existsBinding("exchange2", "queue1"), true);
    ASSERT_EQ(_host->existsBinding( "exchange3", "queue1"), true);

    ASSERT_EQ(_host->existsBinding("exchange3", "queue2" ), true);
    ASSERT_EQ(_host->existsBinding("exchange1", "queue3"), true);

    rbmq::MessagePtr msg1 = _host->basicConsume("queue1");
    ASSERT_EQ(msg1->payload().body(), string("hello world!1"));

    rbmq::MessagePtr msg2 = _host->basicConsume("queue1");
    ASSERT_EQ(msg2->payload().body(), string("hello world!2"));

    rbmq::MessagePtr msg3 = _host->basicConsume("queue1");
    ASSERT_EQ(msg3->payload().body(), string("hello world!3"));
    
}


int main(int argc, char* args[]) {
    testing::InitGoogleTest(&argc, args);
    // testing::AddGlobalTestEnvironment(new HostTest());
    RUN_ALL_TESTS();
    return 0;
}


